#include<vector>
#include<unordered_map>
#include<string>
#include<iostream>
using std::string;
using std::vector;
using std::unordered_map;


struct Ans {
    bool hasPath;
    double val;
};

class Solution {
private:
   unordered_map<string, vector<int>> graph;
   vector<vector<string>> edges;
   vector<double> vals;
   unordered_map<string, int> visited;
   int count;



    void insertPair(vector<string>& pair, int index) {
        for (int i = 0; i < 2; i++) {
            if (graph.find(pair[i]) == graph.end()) {
                graph[pair[i]] = {index};
                visited[pair[i]] = 0;
            }
            else graph[pair[i]].push_back(index);
        }
    }

    double getValue(int index, string& A) {
        if (A == edges[index][0]) return vals[index];
        else return 1.0 / vals[index];
    }

    int nextIndex(string& s, int index) {
        // return the other index of node
        if (edges[index][0] == s) return 1;
        else return 0;
    }

    Ans dfs(string& u, string& v) {
        visited[u] = count;
        if (u == v) return {true, 1};
        for (auto& nextPair: graph[u]) {
            int idx = nextIndex(u, nextPair);
            if (visited[edges[nextPair][idx]] == count) continue;
            auto ans = dfs(edges[nextPair][idx], v);
            if (ans.hasPath) {
                ans.val *= getValue(nextPair, u);
                return ans;
            }
        }
        return {false, -1.0};

    }

public:
    vector<double> calcEquation(vector<vector<string>>& equations, vector<double>& values, vector<vector<string>>& queries) {
        edges = equations;
        vals = values;
        count = 0;
        
        // build graph
        for (int i = 0; i < equations.size(); i++) {
            insertPair(equations[i], i);
        }
        
        // iter queries
        vector<double> ans;
        for (auto& v: queries) {
            count++;
            if (graph.find(v[0]) != graph.end() && graph.find(v[1]) != graph.end()) {
                Ans res = dfs(v[0], v[1]);
                ans.push_back(res.val);
            }
            else ans.push_back(-1.0);
        }

        return ans;
    }

    
};